package cn.buk.tms.eotms.service;

import cn.buk.common.JsonResult;
import cn.buk.common.sc.CommonSearchCriteria;
import cn.buk.common.util.DateUtil;
import cn.buk.tms.common.constant.TmsOrderConstant;
import cn.buk.tms.common.dto.base.BasePassengerDto;
import cn.buk.tms.eotms.dao.AttractionDao;
import cn.buk.tms.eotms.dao.OrderNoGenerator;
import cn.buk.tms.eotms.dto.AttractionInfoDto;
import cn.buk.tms.eotms.dto.AttractionPriceDto;
import cn.buk.tms.eotms.dto.TicketOrderRequestDto;
import cn.buk.tms.eotms.dto.TicketOrderResponseDto;
import cn.buk.tms.eotms.entity.*;
import cn.buk.tms.eotms.sc.SearchFlightOrderCriteria;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * 景点内容相关的服务方法
 */
@Service
public class AttractionServiceImpl extends BaseAbstractService implements AttractionService {

  private final Logger logger = LogManager.getLogger(AttractionServiceImpl.class);

  @Autowired
  private AttractionDao dao;

  @Autowired
  private OrderNoGenerator orderNoGenerator;

  @Override
  public AttractionInfoDto getAttractionInfoById(int userId, int id) {
    AttractionInfo info = dao.getAttractionInfoById(id);

    return AttractionInfoDto.createdBy(info);
  }

  @Override
  public List<AttractionInfoDto> searchAttractions(int userId, CommonSearchCriteria sc) {
    List<AttractionInfo> infos = dao.searchAttractions(userId, sc);

    List<AttractionInfoDto> dtos = new ArrayList<>();
    for(AttractionInfo info: infos) {
      AttractionInfoDto dto = AttractionInfoDto.createdBy(info);
      dtos.add(dto);
    }

    return dtos;
  }

  @Override
  public List<AttractionPriceDto> searchAttractionPrice(int userId, int attractionId, CommonSearchCriteria sc) {
    List<AttractionPrice> prices = dao.searchAttractionPrices(userId, attractionId, sc);

    List<AttractionPriceDto> dtos = new ArrayList<>();
    for(AttractionPrice price: prices) {
      AttractionPriceDto priceDto = new AttractionPriceDto();
      BeanUtils.copyProperties(price, priceDto);

      dtos.add(priceDto);
    }

    return dtos;
  }

  @Override
  public JsonResult createAttractionTicketOrder(final int userId, TicketOrderRequestDto dto) {
    final int ownerId = getOwnerIdByUserId(userId);
    final int customerId = getCustomerIdByUserId(userId);
    final String username = getUsernameByUserId(userId);

    TicketOrder ticketOrder = new TicketOrder();
    ticketOrder.setEnterpriseId(ownerId);

    Customer c = new Customer();
    c.setId(customerId);
    ticketOrder.setCustomer(c);

    AttractionInfo attractionInfo = dao.getAttractionInfoById(dto.getAttractionId());
    ticketOrder.setAttractionInfo(attractionInfo);

    ticketOrder.setOperator(username);
    ticketOrder.setPrice(dto.getPrice());
    ticketOrder.setCount(dto.getCount());
    ticketOrder.setRemark(dto.getRemark());
    ticketOrder.setTotal(dto.getTotal());
    ticketOrder.setTravelDate(dto.getTravelDate());

    for(BasePassengerDto psgDto: dto.getPassengers()) {
      TicketOrderPassenger psg = new TicketOrderPassenger();
      psg.setEnterpriseId(ownerId);
      psg.setOrder(ticketOrder);

      if (psgDto.getName() == null || psgDto.getName().trim().length() < 2) {
        continue;
      }

      psg.setName(psgDto.getName());
      psg.setIdNo(psgDto.getIdNo());
      psg.setMobile(psgDto.getMobile());

      ticketOrder.getPassengers().add(psg);
    }

    if (ticketOrder.getPassengers().size() == 0) {
      return JsonResult.createJsonResult(-1, "请填写游客姓名");
    }

    ticketOrder.setOrderNo(orderNoGenerator.generateOrderNo(ownerId, TmsOrderConstant.ORDER_NO_TICKET));

    try {
      int retCode = dao.createTicketOrder(userId, ticketOrder);
      return JsonResult.createJsonResult(retCode);
    } catch (Exception ex) {
      ex.printStackTrace();
      return JsonResult.createJsonResult(-100, ex.getMessage());
    }
  }

  @Override
  public List<TicketOrderResponseDto> searchTicketOrders(int userId, SearchFlightOrderCriteria sc) {
    final int ownerId = getOwnerIdByUserId(userId);
    final int customerId = getCustomerIdByUserId(userId);

//    Set<String> roles = getRolesByUserId(enterpriseId, userId);
//    //管理员可以查看所有的员工信息
//    //其它可以查看本部门所有的员工信息
//    if (roles.contains(RoleInfo.ROLE_ADMIN)) {
//      //管理员可以查看所有部门的订单
//    } else if (roles.contains(RoleInfo.ROLE_MANAGER) || roles.contains(RoleInfo.ROLE_APPROVER)){
//      //只能查看本部门的
//      int deptId = getCustomerDeptIdByUserId(userId);
//      sc.setDepartmentId(deptId);
//    } else {
//      //只能查看自己的订单
//      sc.setOp1(username);
//    }

    List<TicketOrder> list = dao.searchTicketOrders(ownerId, customerId, sc);

    List<TicketOrderResponseDto> dtos = new ArrayList<>();

    for(TicketOrder info : list) {
      dtos.add(TicketOrderResponseDto.createdBy(info));
    }

    return dtos;

  }

  @Override
  public TicketOrderResponseDto getTicketOrder(int userId, int orderId) {
    TicketOrder ticketOrder = dao.getTicketOrderById(orderId);
    if (ticketOrder == null) {
      return null;
    } else {
      return TicketOrderResponseDto.createdBy(ticketOrder);
    }
  }

  @Override
  public JsonResult cancelTicketOrder(final int userId, int orderId, String remark) {
    try {
      final int ownerId = getOwnerIdByUserId(userId);
      final int customerId = getCustomerIdByUserId(userId);
      final String username = getUsernameByUserId(userId);

      int retCode = dao.cancelTicketOrder(ownerId, customerId, username, orderId, remark);
      return JsonResult.createJsonResult(retCode);
    } catch (Exception ex) {
      ex.printStackTrace();
      return JsonResult.createJsonResult(-100, ex.getMessage());
    }
  }

  @Override
  public JsonResult payTicketOrder(final int userId, final int orderId) {
    final int ownerId = getOwnerIdByUserId(userId);
    final int customerId = getCustomerIdByUserId(userId);
    final int customerEnterpriseId = getEnterpriseIdByUserId(userId);
    //1、用账户余额支付
    try {
      int retCode = dao.payTicketOrder(ownerId, customerEnterpriseId, customerId, userId, orderId);
      return JsonResult.createJsonResult(retCode);
    } catch (RuntimeException ex) {
      return JsonResult.createJsonResult(-100, ex.getMessage());
    }

    //2.上一步不成功，则转到在线支付
//    return null;
  }

  @Override
  public JsonResult importTicketOrderByExcel(final int userId, final String fileName) {
    final int ownerId = getOwnerIdByUserId(userId);
    TicketOrder ticketOrder = new TicketOrder();
    try {
      File target = new File(fileName);
      FileInputStream fi = new FileInputStream(target);
      Workbook wb = create(fi);

      Sheet sheet = wb.getSheetAt(0);
      final int rowNum = sheet.getLastRowNum() + 1;
      logger.info("excel rows: " + rowNum);

      Row row = sheet.getRow(1);
      //景点信息
      final String attractionName = getStringCellValue(row.getCell(0));
      AttractionInfo attractionInfo = dao.getAttractionInfoByName(ownerId, attractionName);
      if (attractionInfo == null) {
        wb.close();
        return JsonResult.createJsonResult(-10, "未找到景点信息");
      }
      ticketOrder.setAttractionInfo(attractionInfo);
      //旅游日期
      final String travelDate = getStringCellValue(row.getCell(1));
      try {
        ticketOrder.setTravelDate(DateUtil.convertToDate(travelDate, "yyyy-MM-dd"));
      } catch (Exception ex) {
        wb.close();
        return JsonResult.createJsonResult(-1, "旅行日期格式不符");
      }
      //张数
      final int count = Integer.parseInt(getStringCellValue(row.getCell(2)));
      ticketOrder.setCount(count);

      for (int i = 3; i < rowNum; i++) {
        row = sheet.getRow(i);

        TicketOrderPassenger psg = new TicketOrderPassenger();

        psg.setName(getStringCellValue(row.getCell(0)));
        psg.setIdNo(getStringCellValue(row.getCell(1)));
        psg.setMobile(getStringCellValue(row.getCell(2)));

        if (psg.getName().trim().length() == 0) {
          continue;
        }

        psg.setOrder(ticketOrder);

        ticketOrder.getPassengers().add(psg);

      }

      if (ticketOrder.getPassengers().size() != count) {
        wb.close();
        return JsonResult.createJsonResult(-2, "人数和名单数不符：" + count + " - " + ticketOrder.getPassengers().size());
      }

//      ticketOrder.setPassengers(passengers);

      wb.close();
    } catch (Exception ex) {
      ex.printStackTrace();
      logger.error(ex.getMessage());
      return JsonResult.createJsonResult(-1, ex.getMessage());
    }

    //查找价格
    AttractionPrice attractionPrice = dao.searchAttractionPriceByDate(ownerId, ticketOrder.getAttractionInfo().getId(), ticketOrder.getTravelDate());
    if (attractionPrice == null) {
      return JsonResult.createJsonResult(-1, "无此日价格");
    }

    ticketOrder.setPrice(attractionPrice.getPrice());
    ticketOrder.setTotal(ticketOrder.getPrice() * ticketOrder.getCount());

    ticketOrder.setEnterpriseId(ownerId);
    final int customerId = getCustomerIdByUserId(userId);
    Customer c = new Customer();
    c.setId(customerId);
    ticketOrder.setCustomer(c);

    final String username = getUsernameByUserId(userId);
    ticketOrder.setOperator(username);

    ticketOrder.setOrderNo(orderNoGenerator.generateOrderNo(ownerId, TmsOrderConstant.ORDER_NO_TICKET));

    int retCode = dao.createTicketOrder(userId, ticketOrder);

    return JsonResult.createJsonResult(retCode);
  }

}
